
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.IO;
using System.Globalization;

namespace ScrewTurn.Wiki {

	public partial class JsImageBrowser : System.Web.UI.UserControl {

		private string hrefCommand, onclickCommand;
		private bool showPreview = true;
		private string[] patterns = new string[] { "*.jpg", "*.jpeg", "*.jpe", "*.bmp", "*.png", "*.gif", "*.tif", "*.tiff" };

		protected void Page_Load(object sender, EventArgs e) {
			RenderContent();
		}

		private string BuildID(string input) {
			int hash = input.GetHashCode();
			if(hash < 0) hash *= -1;
			return "i" + hash.ToString();
		}

		/// <summary>
		/// Renders the content of the control.
		/// </summary>
		public void RenderContent() {
			StringBuilder sb = new StringBuilder();
			if(showPreview) {
				sb.Append(@"<div id=""ImagePreviewDiv"">");
				sb.Append(@"<a id=""PreviewLink"" title=""");
				sb.Append(Resources.Messages.FullView);
				sb.Append(@""" target=""_blank""><img id=""PreviewImg"" src=""Images/Void.png"" alt=""");
				sb.Append(Resources.Messages.Preview);
				sb.Append(@""" /></a><br />");
				sb.Append(@"<span id=""ImageDescriptionSpan"">&nbsp;</span>");
				sb.Append("</div>");
			}
			sb.Append(@"<div id=""MainContainerDiv"">");
			PrintSubDirectory(Settings.UploadDirectory, sb, false, "");
			sb.Append("</div>");

			lblContent.Text = string.Format("<script type=\"text/javascript\">\n<!--\nvar __JsBrowserContent = \"{0}\";\n// -->\n</script>",
				sb.ToString().Replace("\"", "&quot;"));
		}

		private void PrintSubDirectory(string path, StringBuilder sb, bool up, string parent) {
			string[] directories = Directory.GetDirectories(path);
			List<string> tmpFiles = new List<string>();
			for(int i = 0; i < patterns.Length; i++) {
				tmpFiles.AddRange(Directory.GetFiles(path, patterns[i]));
			}
			tmpFiles.Sort();
			string[] files = tmpFiles.ToArray();
			tmpFiles = null;

			sb.Append(@"<div id=""dir");
			sb.Append(BuildID(path));
			sb.Append(@"""");
			if(up) sb.Append(@" style=""display: none;""");
			sb.Append(">");

			// Print UpLevel
			if(up) {
				// Link to parent directory, that is exactly path
				sb.Append(@"<div class=""container""><a href=""#"" onclick=""javascript:return __SwapStatus('dir");
				sb.Append(BuildID(parent));
				sb.Append(@"', 'dir");
				sb.Append(BuildID(path));
				sb.Append(@"');"" Id=""UpLevelLink""><img class=""thumb"" src=""Images/DirectoryUp.png"" alt=""Up"" /></a></div>");
			}

			// Print Directories
			for(int i = 0; i < directories.Length; i++) {
				sb.Append(@"<div class=""container""><a href=""#"" onclick=""javascript:return __SwapStatus('dir");
				sb.Append(BuildID(directories[i]));
				sb.Append(@"', 'dir");
				sb.Append(BuildID(path));
				sb.Append(@"');"" class=""dirlink""><img class=""thumb"" src=""Images/Directory.png"" alt=""Dir"" /><br /><span class=""itemtext"">");
				sb.Append(Path.GetFileName(directories[i]));
				sb.Append("</span></a></div>");
			}

			// Print Files
			for(int i = 0; i < files.Length; i++) {
				sb.Append(@"<div class=""container""><a href=""");
				sb.Append(hrefCommand.Replace("$", Tools.UrlEncode(files[i].Substring(Settings.UploadDirectory.Length).Replace("\\", "/"))));
				sb.Append(@""" onmouseup=""");
				if(showPreview) {
					sb.Append("javascript:return __ShowPreview('GetThumb.aspx?Big=1&Image=");
					sb.Append(UrlEncode(files[i].Substring(Settings.UploadDirectory.Length)));
					sb.Append("', '");
					sb.Append(UrlEncode(Path.GetFileName(files[i])));
					sb.Append("', 'GetFile.aspx?File=");
					sb.Append(UrlEncode(files[i].Substring(Settings.UploadDirectory.Length).Replace("\\", "/")));
					sb.Append("');");
				}
				sb.Append(@""" onclick=""");
				sb.Append(onclickCommand.Replace("$", UrlEncode(files[i].Substring(Settings.UploadDirectory.Length).Replace("\\", "/"))));
				sb.Append(@""" class=""itemlink"" title=""");
				sb.Append(Server.HtmlEncode(Path.GetFileName(files[i])));
				sb.Append(@""">");
				sb.Append(@"<img class=""thumb"" src=""GetThumb.aspx?Image=");
				sb.Append(Tools.UrlEncode(files[i].Substring(Settings.UploadDirectory.Length)));
				sb.Append(@""" alt=""Thumb"" />");
				sb.Append(@"<br /><span class=""itemtext"">");
				sb.Append(PrepareFilename(Path.GetFileName(files[i])));
				sb.Append("</span></a></div>");
			}

			sb.Append("</div>");

			// Print all subdirs
			for(int i = 0; i < directories.Length; i++) {
				PrintSubDirectory(directories[i], sb, true, path);
			}

		}

		private string PrepareFilename(string filename) {
			int limit = 12;
			if(filename.Length > limit) {
				int idx = filename.IndexOf(" ");
				if(idx >= 0 && idx <= limit - 1 && idx + limit - 3 < filename.Length) {
					return filename.Substring(0, idx + limit - 3) + ".." + Path.GetExtension(filename).ToLower(CultureInfo.CurrentCulture);
				}
				else {
					//return filename.Substring(0, limit) + "<br />" + filename.Substring(limit);
					return filename.Substring(0, limit - 3) + ".." + Path.GetExtension(filename).ToLower(CultureInfo.CurrentCulture);
				}
			}
			else return filename;
		}

		private string UrlEncode(string input) {
			// Used because the JS Image Browser control markup is stored in a string
			// and displayed only when needed, and this process breaks single quotes
			return Tools.UrlEncode(input).Replace("'", ":::::APOS:::::");
		}

		/// <summary>
		/// Gets or sets the Href file command.
		/// </summary>
		public string HrefCommand {
			get { return hrefCommand; }
			set { hrefCommand = value; }
		}

		/// <summary>
		/// Gets or sets the OnClick file command.
		/// </summary>
		public string OnClickCommand {
			get { return onclickCommand; }
			set { onclickCommand = value; }
		}

		public bool ShowPreview {
			get { return showPreview; }
			set { showPreview = value; }
		}

	}

}
